<?php 
class np_redis_check_class
{
	//压缩头
	private $zip_header = "ZIP##";
	//redis实例
	private $redis_inst = null;
	//队列名称
	private $queue_name = '';
	//指令回收模式
	private $recover_mode = "loop";
	//指令失效时长
	private $command_lose_time = 86400;
   /**
	* 构造函数，传递redis队列参数
	*  config["queue_name"] 队列名称
	*  config["recover_mode"] 指令回收模式，loop为回收到队列尾部，push 为回收到队列头部 ，默认为push
	*  config["command_lose_time"] 指令失效时长，默认为，24*3600 s
	*/
	public function __construct($redis,$config)
	{	
		if (empty($config["queue_name"]))
		{
			return false;
		}
		$this->queue_name = $config["queue_name"];
		if (!empty($config["recover_mode"]))
		{
			$this->recover_mode = $config["recover_mode"];
		}
		if (!empty($config["command_lose_time"]))
		{
			$this->command_lose_time = $config["command_lose_time"];
		}
		$this->redis_inst = $redis;
	}

	/**
	 * 添加redis指令
	 * @param string $command 指令内容
	 * @return boolean
	 */
	public function add_command($command)
	{
		if (empty($this->queue_name))
		{
			return false;
		}
		$arr = array();
		$arr["time"] = date("Y-m-d H:i:s");
		$arr["command"] = $command;
		$data = $this->_zip_value($arr);
		if ($this->recover_mode == "loop")
		{
			$bool = $this->redis_inst->rpush($this->queue_name,$data);
		}
		else 
		{
			$bool = $this->redis_inst->lpush($this->queue_name,$data);
		}
		return $bool;
	}
	/**
	 * 获取指令，返回指令对象
	 * @param int $limit 获取条数
	 * @return array
	 */
	public function get_command($limit = 1)
	{
		$result = array();
		$i = 0;
		$now_time = time();
		while($i < $limit)
		{
			if ($this->recover_mode == "loop")
			{
				$data = $this->redis_inst->lpop($this->queue_name);
			}
			else 
			{
				$data = $this->redis_inst->rpop($this->queue_name);
			}
			if (empty($data))
			{
				break;
			}
			$data = $this->_unzip_value($data);
			$insert_time =  strtotime($data["time"]);
			if ($now_time - $insert_time < $this->command_lose_time)
			{
				$result[] = $data;
				$i++;
			}
		}
		return $result;
	}
	/**
	 * 回收队列指令，为一个数组
	 * @return array boolean
	 */
	public function recover_command($list_command)
	{
		$this->redis_inst->multi(Redis::PIPELINE);
		foreach ($list_command as $command_data)
		{
			$data = $this->_zip_value($command_data);
			if ($this->recover_mode == "loop")
			{
				$this->redis_inst->rpush($this->queue_name,$data);
			}
			else
			{
				$this->redis_inst->lpush($this->queue_name,$data);
			}
		}
		$result = $this->redis_inst->exec();
		$result = end($result);
		return $result;
	}
	/**
	 * 返回数据列表，分页返回,如果没有了，则返回null
	 * @param int $start 起始数
	 * @param int $end   结束数
	 * @return array
	 */
	public function get_list($start,$end)
	{
		$result = array();
		$data = $this->redis_inst->lrange($this->queue_name,$start,$end);
		if (empty($data))
		{
			return null;
		}
		$result['num'] = $this->redis_inst->llen($this->queue_name);
		foreach ($data as $item)
		{
			$item = $this->_unzip_value($item);
			$result['data'][] = $item;
		}
		return $result;
	}
	/**
	 * 对字符串进行压缩，当字符串小于256，则不进行压缩
 	 * @param array $value  要说数组
     * @return string
	 */
	private function _zip_value($value)
	{
		if (!is_array($value) && empty($value))
		{
			return $value;
		}
		$value = serialize($value);
		$len = strlen($value);
		if ($len > 256 )
		{
			$zip_value = gzcompress($value);
			return $this->zip_header.$zip_value;
		}
		return $value;
	}
	/**
	 * 对字符串进行解压
	 * @param $value
	 * @return string
	 * 
	 */
	private function _unzip_value($value)
	{
		if (empty($value))
		{
        	return $value;
        }
		$zip_flag = substr($value,0,5);
        if ($zip_flag == $this->zip_header)
        {
        	$zip_value = substr($value,5);
            return unserialize(gzuncompress($zip_value));
        }
		return unserialize($value);
	}
}